package com.link.base.base.autoconfig.nocode.service;

import com.link.base.base.autoconfig.nocode.model.SourceCodeObject;
import com.link.core.basic.service.ServiceException;
import com.link.core.cllog.LCLogger;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 遍历nocode服务
 *
 * @author 何启谦
 * @date 2019/9/28
 */
@Service
public class NoCodeServiceImpl implements NoCodeService {

    @Resource
    private RestTemplate restNoLbTemplate;
    @Resource
    private DiscoveryClient discoveryClient;

    /**
     * nocode服务默认名称
     */
    private static final String DEFAULT_SERVICE_NAME = "link-nocode";

    /**
     * 获取nocode的实例
     */
    private List<ServiceInstance> getServiceInstance() {
        /*String serviceName = env.getProperty("gateway.servicename");
        if (StringUtils.isBlank(serviceName)) {
            serviceName = DEFAULT_SERVICE_NAME;
        } else {
            serviceName = serviceName.toLowerCase();
        }*/

        return discoveryClient.getInstances(DEFAULT_SERVICE_NAME);
    }

    private void postForObject(String url, Object param) {
        List<ServiceInstance> instanceList = getServiceInstance();
        if (instanceList == null || instanceList.isEmpty()) {
            throw new ServiceException("未找到nocode服务");
        }
        for (ServiceInstance serviceInstance : instanceList) {
            String homeUrl = ((EurekaDiscoveryClient.EurekaServiceInstance) serviceInstance).getInstanceInfo().getHomePageUrl();
            String path = homeUrl + url;
            LCLogger.info().withMessageKey("NoCodeServiceImpl.postForObject.path").withMessage(path).flush();

            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.add("NoIntercept", "NoIntercept");

            HttpEntity<Object> requestEntity = new HttpEntity<>(param, requestHeaders);
            ResponseEntity<Map> responseEntity = restNoLbTemplate.exchange(path, HttpMethod.POST, requestEntity, Map.class);
            Map<String, Object> response = responseEntity.getBody();

            if (response == null) {
                throw new ServiceException("调用nocode接口报错，url：" + path);
            }
            Boolean deployFlag = (Boolean) response.get("success");
            if (!deployFlag) {
                throw new ServiceException(ObjectUtils.nullSafeToString(response.get("result")));
            }
        }
    }

    /**
     * 将代码部署到所有nocode服务中
     */
    @Override
    public void deployToAllApp(SourceCodeObject sourceCodeObject) {
        postForObject("/nocode/generator/deploy", sourceCodeObject);
    }

    /**
     * 从所有nocode服务中卸载指定代码模块
     */
    @Override
    public void uninstallModularForUUID(String uuid) {
        Map<String, Object> param = new HashMap<>();
        param.put("modularUUID", uuid);
        postForObject("/nocode/generator/uninstallModularForUUID", param);
    }

    /**
     * 从所有nocode服务中校验代码模块
     */
    @Override
    public void checkCode(SourceCodeObject sourceCodeObject) {
        postForObject("/nocode/generator/checkCode", sourceCodeObject);
    }
}
